#include "taskQueue.h"

void task_queue_init(task_queue_t *q)
{
    // 如果传入的队列指针为空，直接返回
    if (q == NULL)
    {
        return;
    }

    bzero(q, sizeof(task_queue_t));

    return;
}

void task_queue_destroy(task_queue_t *q)
{
    // 如果传入的队列指针为空，直接返回
    if (q == NULL)
    {
        return;
    }

    // 逐个出队并释放节点
    task_node_t *current = q->front;
    task_node_t *next;
    for (int i = 0; i < q->size; i++)
    {
        // 保存下一个节点
        next = current->next;
        // TODO: 释放用户会话中的栈
        // 注意：不在这里释放 session（调用者负责释放 session 中的资源）
        // 释放节点
        free(current);
        // 移动到下一个节点
        current = next;
    }

    // 清空队列字段，但不 free q 本身（调用者可能在栈上或由其他模块管理）
    q->front = NULL;
    q->rear = NULL;
    q->size = 0;

    return;
}

int task_node_create(task_node_t **node_buf_ptr, clientSession_t *session)
{
    // 如果传入的指针为空，直接返回错误
    if (node_buf_ptr == NULL || session == NULL)
    {
        return -1;
    }

    // 创建新节点
    task_node_t *new_node = (task_node_t *)malloc(sizeof(task_node_t));
    if (new_node == NULL)
    {
        LOG_ERROR("task_node_create: malloc failed");
        return -1;
    }

    // 初始化节点
    new_node->session = session;
    new_node->next = NULL;
    // 返回节点指针
    *node_buf_ptr = new_node;

    return 0;
}

int task_queue_enqueue(task_queue_t *q, clientSession_t *session)
{
    // 如果传入的队列指针或节点指针为空，直接返回错误
    if (q == NULL || session == NULL)
    {
        return -1;
    }

    // 创建新节点
    task_node_t *new_node;
    int ret = task_node_create(&new_node, session);
    // 错误处理
    if (ret < 0)
    {
        return -1;
    }

    // 如果队列为空，同时修改头尾指针的指向
    if (q->size == 0)
    {
        q->front = new_node;
        q->rear = new_node;
        q->size++;

        return 0;
    }
    // 正常的入队逻辑
    q->rear->next = new_node;
    q->rear = new_node;
    q->size++;

    return 0;
}

int task_queue_dequeue(task_queue_t *q)
{
    // 如果传入的队列指针为空或队列为空，直接返回错误
    if (q == NULL || q->size == 0)
    {
        return -1;
    }

    // 取出队头节点
    task_node_t *front_node = q->front;

    // 如果队列中只有一个节点，需要同时修改头尾指针
    if (q->size == 1)
    {
        q->front = NULL;
        q->rear = NULL;
        q->size--;

        free(front_node);
        return 0;
    }

    q->front = front_node->next;
    q->size--;
    free(front_node);

    return 0;
}